import { Inject, Provide } from "@midwayjs/core";
import { BaseService, CoolCommException, CoolTransaction } from "@cool-midway/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { EntityManager, In, Repository, QueryRunner, Equal } from "typeorm";
import { OrderAssignEntity } from "../../order/entity/assign";
import { OrderItemEntity } from "../../order/entity/item";
import { OrderInfoEntity } from "../../order/entity/info";
import { ProviderInfoEntity } from "../../provider/entity/info";
import { CarInfoEntity } from "../../transport/entity/car/info";
import { ProviderTeamEntity } from "../../provider/entity/team";
import { ProviderProfileEntity } from "../../provider/entity/profile";
import { CapacityEntity } from "../../transport/entity/capacity";
import { ProviderPartnerEntity } from "../../provider/entity/partner";
import { Context } from "@midwayjs/koa";

/**
 * 分配服务与车辆
 */
@Provide()
export class OrderAssignService extends BaseService {
    @InjectEntityModel(OrderAssignEntity)
    orderAssignEntity: Repository<OrderAssignEntity>;

    @InjectEntityModel(OrderItemEntity)
    orderItemEntity: Repository<OrderItemEntity>;

    @InjectEntityModel(OrderInfoEntity)
    orderInfoEntity: Repository<OrderInfoEntity>;

    @InjectEntityModel(ProviderInfoEntity)
    providerInfoEntity: Repository<ProviderInfoEntity>;

    @InjectEntityModel(CarInfoEntity)
    carInfoEntity: Repository<CarInfoEntity>;

    @InjectEntityModel(ProviderTeamEntity)
    providerTeamEntity: Repository<ProviderTeamEntity>;

    @InjectEntityModel(ProviderProfileEntity)
    providerProfileEntity: Repository<ProviderProfileEntity>;

    @InjectEntityModel(CapacityEntity)
    capacityEntity: Repository<CapacityEntity>;

    @InjectEntityModel(ProviderPartnerEntity)
    providerPartnerEntity: Repository<ProviderPartnerEntity>;

    @Inject()
    ctx: Context;

    /**
     * 分配/重新分配：将当前有效分配置为已释放，新增一条已分配记录
     */
    @CoolTransaction()
    async assign(
        params: { itemId: number; providerId?: number; vehicleId?: number },
        queryRunner?: QueryRunner
    ) {
        const { itemId, providerId, vehicleId } = params || {};
        if (!itemId) throw new CoolCommException('缺少 itemId');

        // 校验团队负责人权限
        await this.verifyTeamLeaderByItemId(itemId);

        // 校验子项存在
        const item = await queryRunner.manager.findOne(OrderItemEntity, { where: { id: itemId } });
        if (!item) throw new CoolCommException('订单子项不存在');

        // 可选校验：服务人员与车辆存在
        if (providerId) {
            const provider = await queryRunner.manager.findOne(ProviderInfoEntity, { where: { id: providerId } });
            if (!provider) throw new CoolCommException('服务人员不存在');
        }
        if (vehicleId) {
            const vehicle = await queryRunner.manager.findOne(CarInfoEntity, { where: { id: vehicleId } });
            if (!vehicle) throw new CoolCommException('车辆不存在');
        }

        // 释放当前有效分配
        await queryRunner.manager.update(OrderAssignEntity, { itemId, status: 1 }, { status: 2 });

        // 新增分配记录
        const assignedTime = new Date().toISOString();
        const insertResult = await queryRunner.manager.insert(OrderAssignEntity, {
            orderId: item.orderId,
            itemId,
            providerId: providerId || null,
            vehicleId: vehicleId || null,
            status: 1,
            assignedTime,
        });
        await this.syncItemFulfillStatus(itemId, queryRunner.manager);
        return insertResult.identifiers?.[0] || true;
    }

    /**
     * 取消分配：将当前有效分配置为已释放
     */
    @CoolTransaction()
    async unassign(params: { itemId: number }, queryRunner?: QueryRunner) {
        const { itemId } = params || {};
        if (!itemId) throw new CoolCommException('缺少 itemId');

        // 校验团队负责人权限
        await this.verifyTeamLeaderByItemId(itemId);

        const item = await queryRunner.manager.findOne(OrderItemEntity, { where: { id: itemId } });
        if (!item) throw new CoolCommException('订单子项不存在');

        await queryRunner.manager.update(OrderAssignEntity, { itemId, status: 1 }, { status: 2 });
        await this.syncItemFulfillStatus(itemId, queryRunner.manager);
        return true;
    }

    /**
     * 服务人员查询分配给自己的子订单
     */
    async myAssignedItems(query: {
        page?: number;
        size?: number;
        status?: number | string;
        orderStatus?: number | string;
        orderType?: string;
        keyword?: string;
    } = {}) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }

        const resolvedQuery = query ?? {};
        // 构建查询：join 子项与主订单，方便一次性返回展示所需字段
        const qb = this.orderAssignEntity
            .createQueryBuilder('a')
            .innerJoin(OrderItemEntity, 'item', 'item.id = a.itemId')
            .innerJoin(OrderInfoEntity, 'info', 'info.id = a.orderId')
            .select('a.id', 'assignId')
            .addSelect('a.orderId', 'orderId')
            .addSelect('a.itemId', 'itemId')
            .addSelect('a.status', 'assignStatus')
            .addSelect('a.assignedTime', 'assignedTime')
            .addSelect('a.vehicleId', 'vehicleId')
            .addSelect('a.executeStatus', 'executeStatus')
            .addSelect('a.executeStatusTime', 'executeStatusTime')
            .addSelect('a.executeRemark', 'executeRemark')
            .addSelect('item.title', 'itemTitle')
            .addSelect('item.unitPrice', 'unitPrice')
            .addSelect('item.quantity', 'quantity')
            .addSelect('item.amount', 'amount')
            .addSelect('item.useTime', 'useTime')
            .addSelect('item.startPlace', 'startPlace')
            .addSelect('item.endPlace', 'endPlace')
            .addSelect('item.extra', 'extra')
            .addSelect('item.productId', 'productId')
            .addSelect('item.productItemId', 'productItemId')
            .addSelect('item.fulfillStatus', 'fulfillStatus')
            .addSelect('item.fulfillStatusTime', 'fulfillStatusTime')
            .addSelect('info.orderNo', 'orderNo')
            .addSelect('info.type', 'orderType')
            .addSelect('info.status', 'orderStatus')
            .addSelect('info.price', 'orderPrice')
            .where('a.providerId = :providerId', { providerId })
            .orderBy('a.id', 'DESC');

        // 分配状态筛选：默认只展示有效分配（status=1）
        const statusFilter = this.parseNumberFilter(resolvedQuery.status);
        if (statusFilter !== undefined) {
            qb.andWhere('a.status = :assignStatus', { assignStatus: statusFilter });
        } else {
            qb.andWhere('a.status = :assignStatus', { assignStatus: 1 });
        }

        // 支持按订单状态过滤
        const orderStatusFilter = this.parseNumberFilter(resolvedQuery.orderStatus);
        if (orderStatusFilter !== undefined) {
            qb.andWhere('info.status = :orderStatus', { orderStatus: orderStatusFilter });
        }

        if (resolvedQuery.orderType) {
            qb.andWhere('info.type = :orderType', { orderType: resolvedQuery.orderType });
        }

        // 关键字支持订单号与子项标题模糊查询
        const keyword = resolvedQuery.keyword?.trim();
        if (keyword) {
            qb.andWhere('(info.orderNo LIKE :keyword OR item.title LIKE :keyword)', {
                keyword: `%${keyword}%`,
            });
        }

        const result = await this.entityRenderPage(qb, resolvedQuery, false);
        // 将扁平查询结果映射为前端友好的结构
        result.list = (result.list || []).map(row => ({
            assignId: row.assignId,
            orderId: row.orderId,
            itemId: row.itemId,
            status: row.assignStatus,
            assignedTime: row.assignedTime,
            vehicleId: row.vehicleId,
            executeStatus: row.executeStatus,
            executeStatusTime: row.executeStatusTime,
            executeRemark: row.executeRemark,
            order: {
                orderNo: row.orderNo,
                type: row.orderType,
                status: row.orderStatus,
                price: row.orderPrice,
            },
            item: {
                title: row.itemTitle,
                unitPrice: row.unitPrice,
                quantity: row.quantity,
                amount: row.amount,
                useTime: row.useTime,
                startPlace: row.startPlace,
                endPlace: row.endPlace,
                extra: row.extra,
                productId: row.productId,
                productItemId: row.productItemId,
                fulfillStatus: row.fulfillStatus,
                fulfillStatusTime: row.fulfillStatusTime,
            },
        }));
        return result;
    }

    /**
     * 服务人员查看某主订单详情（仅返回与自己相关的子项）
     */
    async orderDetailForProvider(orderId: number) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }
        if (!orderId) throw new CoolCommException('缺少 orderId');

        const order = await this.orderInfoEntity.findOne({ where: { id: orderId } });
        if (!order) throw new CoolCommException('订单不存在');

        const assigns = await this.orderAssignEntity.find({ where: { orderId, providerId } });
        if (!assigns.length) {
            throw new CoolCommException('无权限查看该订单');
        }

        const itemIds = assigns.map(a => a.itemId).filter(Boolean);
        const items = itemIds.length
            ? await this.orderItemEntity.find({ where: { id: In(itemIds) } })
            : [];
        const assignMap = new Map(assigns.map(a => [a.itemId, a]));

        return {
            order,
            items: items.map(item => ({
                ...item,
                assign: assignMap.get(item.id) || null,
            })),
        };
    }

    /**
     * 服务人员查看单个子订单详情，包含主订单与当前分配信息
     */
    async itemDetailForProvider(itemId: number) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }
        if (!itemId) throw new CoolCommException('缺少 itemId');

        const assign = await this.orderAssignEntity.findOne({ where: { itemId, providerId } });
        if (!assign) {
            throw new CoolCommException('无权限查看该子订单');
        }

        const item = await this.orderItemEntity.findOne({ where: { id: itemId } });
        if (!item) throw new CoolCommException('订单子项不存在');

        const order = await this.orderInfoEntity.findOne({ where: { id: item.orderId } });
        if (!order) throw new CoolCommException('订单不存在');

        return {
            order,
            item,
            assign,
        };
    }

    /**
     * 服务人员更新执行状态
     */
    async updateExecuteStatus(params: { assignId: number; executeStatus: number; remark?: string }) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }
        const { assignId, executeStatus, remark } = params || ({} as any);
        if (!assignId) throw new CoolCommException('缺少 assignId');
        if (executeStatus === undefined || executeStatus === null) {
            throw new CoolCommException('缺少 executeStatus');
        }
        // 限制只能操作当前服务人员的分配记录
        const assign = await this.orderAssignEntity.findOne({ where: { id: assignId, providerId } });
        if (!assign) throw new CoolCommException('分配不存在或无权操作');
        if (assign.status !== 1) {
            throw new CoolCommException('当前分配已失效，无法操作');
        }
        const executeStatusTime = new Date().toISOString();
        await this.orderAssignEntity.update(assignId, {
            executeStatus,
            executeStatusTime,
            executeRemark: remark ?? assign.executeRemark,
        });
        await this.syncItemFulfillStatus(assign.itemId);
        return true;
    }

    private parseNumberFilter(value: any) {
        if (value === undefined || value === null || value === '') {
            return undefined;
        }
        const num = Number(value);
        if (Number.isNaN(num)) {
            throw new CoolCommException('数值参数不合法');
        }
        return num;
    }

    /**
     * 根据当前有效分配情况同步子订单履约状态
     */
    private async syncItemFulfillStatus(itemId: number, manager?: EntityManager) {
        const em = manager || this.orderAssignEntity.manager;
        const assigns = await em.find(OrderAssignEntity, { where: { itemId, status: 1 } });
        const nextStatus = this.resolveFulfillStatus(assigns);
        await em.update(OrderItemEntity, { id: itemId }, {
            fulfillStatus: nextStatus,
            fulfillStatusTime: new Date().toISOString(),
        });
    }

    /**
     * 通过单个分配的执行状态推导子订单履约态
     */
    private resolveFulfillStatus(assigns: OrderAssignEntity[]) {
        if (!assigns.length) {
            return 0;
        }
        const executeStatuses = assigns.map(a => a.executeStatus ?? 0);
        if (executeStatuses.includes(2)) {
            return 2;
        }
        if (executeStatuses.includes(3)) {
            return 3;
        }
        if (executeStatuses.every(status => status === 4)) {
            return 4;
        }
        if (executeStatuses.every(status => status === 5)) {
            return 5;
        }
        return 1;
    }

    /**
     * 获取当前服务人员所在的团队ID
     * - 如果是团队所有者,返回团队ID
     * - 如果是团队成员,返回所属团队ID
     */
    private async getCurrentTeamId(): Promise<number | null> {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            return null;
        }

        // 优先判断是否是团队所有者
        const ownerTeam = await this.providerTeamEntity.findOne({
            where: { ownerProviderId: Equal(providerId) },
        });
        if (ownerTeam) {
            return ownerTeam.id;
        }

        // 非团队所有者:查询加入的团队(通过运力 teamId 反查团队)
        const profile = await this.providerProfileEntity.findOne({
            where: { providerId: Equal(providerId) },
        });
        if (!profile) {
            return null;
        }

        const myCapacity = await this.capacityEntity.findOne({
            where: { id: Equal(profile.capacityId) },
        });
        return myCapacity?.teamId ?? null;
    }

    /**
     * 判断当前服务人员是否为团队负责人
     */
    private async isTeamLeader(): Promise<boolean> {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            return false;
        }

        const ownerTeam = await this.providerTeamEntity.findOne({
            where: { ownerProviderId: Equal(providerId) },
        });
        return !!ownerTeam;
    }

    /**
     * 获取团队下所有服务人员ID(包括所有者、所属成员、合作成员)
     */
    private async getTeamMemberIds(teamId: number): Promise<number[]> {
        if (!teamId) {
            return [];
        }

        const team = await this.providerTeamEntity.findOne({
            where: { id: Equal(teamId) },
        });
        if (!team) {
            return [];
        }

        const memberIds: number[] = [team.ownerProviderId];

        // 查询合作成员
        const partners = await this.providerPartnerEntity.find({
            where: { teamId: Equal(teamId) },
        });
        memberIds.push(...partners.map(p => p.providerId));

        // 查询所属成员(通过运力查询)
        const capacities = await this.capacityEntity.find({
            where: { teamId: Equal(teamId) },
        });
        const capacityIds = capacities.map(c => c.id);
        if (capacityIds.length > 0) {
            const profiles = await this.providerProfileEntity.find({
                where: { capacityId: In(capacityIds) },
            });
            memberIds.push(...profiles.map(p => p.providerId));
        }

        // 去重
        return [...new Set(memberIds)];
    }

    /**
     * 服务人员查询主订单列表(含子订单)
     * - 普通成员:只能查看分配给自己的订单
     * - 团队负责人:可以查看团队下所有订单
     */
    async myOrders(query: {
        page?: number;
        size?: number;
        status?: number | string;
        keyword?: string;
    } = {}) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }

        const isLeader = await this.isTeamLeader();
        const teamId = await this.getCurrentTeamId();

        let targetProviderIds: number[] = [];

        if (isLeader && teamId) {
            // 团队负责人:获取团队下所有成员ID
            targetProviderIds = await this.getTeamMemberIds(teamId);
        } else {
            // 普通成员:只查自己的
            targetProviderIds = [providerId];
        }

        if (!targetProviderIds.length) {
            return { list: [], total: 0, pagination: { page: 1, size: 10 } };
        }

        // 查询分配给目标服务人员的订单ID
        const assigns = await this.orderAssignEntity.find({
            where: {
                providerId: In(targetProviderIds),
                status: 1, // 只查有效分配
            },
        });

        if (!assigns.length) {
            return { list: [], total: 0, pagination: { page: 1, size: 10 } };
        }

        const orderIds = [...new Set(assigns.map(a => a.orderId))];

        // 构建主订单查询
        const qb = this.orderInfoEntity
            .createQueryBuilder('o')
            .where('o.id IN (:...orderIds)', { orderIds })
            .orderBy('o.id', 'DESC');

        // 订单状态筛选
        const statusFilter = this.parseNumberFilter(query.status);
        if (statusFilter !== undefined) {
            qb.andWhere('o.status = :status', { status: statusFilter });
        }

        // 关键字搜索(订单号)
        const keyword = query.keyword?.trim();
        if (keyword) {
            qb.andWhere('o.orderNo LIKE :keyword', { keyword: `%${keyword}%` });
        }

        const result = await this.entityRenderPage(qb, query, false);

        // 为每个订单关联子订单和分配信息
        const finalOrderIds = result.list.map((o: any) => o.id);
        if (finalOrderIds.length > 0) {
            // 查询子订单
            const items = await this.orderItemEntity.find({
                where: { orderId: In(finalOrderIds) },
            });

            // 查询分配信息
            const itemIds = items.map(i => i.id);
            const itemAssigns = itemIds.length
                ? await this.orderAssignEntity.find({
                      where: { itemId: In(itemIds), status: 1 },
                  })
                : [];

            // 按订单ID分组
            const orderIdToItems = new Map<number, any[]>();
            items.forEach(item => {
                if (!orderIdToItems.has(item.orderId)) {
                    orderIdToItems.set(item.orderId, []);
                }
                // 关联分配信息
                const itemAssign = itemAssigns.find(a => a.itemId === item.id);
                orderIdToItems.get(item.orderId)!.push({
                    ...item,
                    assign: itemAssign || null,
                });
            });

            // 合并数据
            result.list = (result.list || []).map((order: any) => ({
                ...order,
                items: orderIdToItems.get(order.id) || [],
            }));
        }

        return result;
    }

    /**
     * 服务人员查询主订单详情(含子订单和分配)
     * - 普通成员:只能查看有分配给自己的订单
     * - 团队负责人:可以查看团队下所有订单
     */
    async myOrderDetail(orderId: number) {
        const providerId = this.ctx?.provider?.id;
        if (!providerId) {
            throw new CoolCommException('登录失效，请重新登录');
        }
        if (!orderId) {
            throw new CoolCommException('缺少 orderId');
        }

        const order = await this.orderInfoEntity.findOne({ where: { id: orderId } });
        if (!order) {
            throw new CoolCommException('订单不存在');
        }

        const isLeader = await this.isTeamLeader();
        const teamId = await this.getCurrentTeamId();

        // 权限校验
        if (!isLeader) {
            // 普通成员:检查是否有该订单的分配记录
            const myAssign = await this.orderAssignEntity.findOne({
                where: { orderId, providerId, status: 1 },
            });
            if (!myAssign) {
                throw new CoolCommException('无权限查看该订单');
            }
        } else if (teamId) {
            // 团队负责人:检查订单是否属于团队成员
            const teamMemberIds = await this.getTeamMemberIds(teamId);
            const teamAssign = await this.orderAssignEntity.findOne({
                where: { orderId, providerId: In(teamMemberIds), status: 1 },
            });
            if (!teamAssign) {
                throw new CoolCommException('该订单不属于您的团队');
            }
        }

        // 查询子订单
        const items = await this.orderItemEntity.find({
            where: { orderId },
        });

        // 查询分配信息
        const itemIds = items.map(i => i.id);
        const assigns = itemIds.length
            ? await this.orderAssignEntity.find({
                  where: { itemId: In(itemIds), status: 1 },
              })
            : [];

        // 关联分配信息到子订单
        const itemsWithAssign = items.map(item => {
            const assign = assigns.find(a => a.itemId === item.id);
            return {
                ...item,
                assign: assign || null,
            };
        });

        return {
            order,
            items: itemsWithAssign,
        };
    }

    /**
     * 验证团队负责人权限（通过子项ID）
     */
    private async verifyTeamLeaderByItemId(itemId: number): Promise<void> {
        // 获取子项信息
        const item = await this.orderItemEntity.findOne({
            where: { id: Equal(itemId) }
        });

        if (!item) {
            throw new CoolCommException('订单子项不存在');
        }

        // 获取订单信息
        const order = await this.orderInfoEntity.findOne({
            where: { id: Equal(item.orderId) }
        });

        if (!order) {
            throw new CoolCommException('订单不存在');
        }

        // 验证团队负责人权限
        await this.verifyTeamLeader(order.teamId);
    }

    /**
     * 验证团队负责人权限
     */
    private async verifyTeamLeader(teamId: number): Promise<void> {
        if (!this.ctx.provider?.id) {
            throw new CoolCommException('请先登录');
        }

        // 检查是否为团队负责人
        const team = await this.providerTeamEntity.findOne({
            where: { id: Equal(teamId), ownerProviderId: Equal(this.ctx.provider.id) }
        });

        if (!team) {
            throw new CoolCommException('只有团队负责人才能进行分配操作');
        }
    }
}


